eletrotupi / tcc/ frontend/app/sleep/edit/[id].tsxdcee93d0c11ceff985805b7785c7db54c2acc4dd
4.9 KB | 178 lines Raw
1
import {
2
  View,
3
  StyleSheet,
4
  KeyboardAvoidingView,
5
  ScrollView,
6
  ActivityIndicator,
7
} from "react-native";
8
import { Text } from "@/components/ui/Text";
9
import { useState } from "react";
10
import { router, useLocalSearchParams, Stack } from "expo-router";
11

12
import { Card } from "@/components/ui/Cards";
13
import { TextArea } from "@/components/ui/Input";
14
import { Button } from "@/components/ui/Button";
15
import { Spacing, Typography, Colors, BorderRadius } from "@/constants/theme";
16
import { Ionicons } from "@expo/vector-icons";
17
import { DatePickerField } from "@/components/ui/DatePickerField";
18
import { ScaleSlider } from "@/components/ui/ScaleSlider";
19
import { useSleepRecord, useUpdateSleepRecord } from "@/hooks";
20
import { parseDateOnly } from "@/lib/utils/time";
21
import type { SleepRecord } from "@/lib/api";
22

23
export default function EditSleepRecord() {
24
  const { id } = useLocalSearchParams<{ id: string }>();
25
  const { data: sleepRecord, isLoading } = useSleepRecord(id);
26

27
  if (isLoading) {
28
    return (
29
      <View style={styles.centered}>
30
        <ActivityIndicator size="large" color={Colors.light.tint} />
31
      </View>
32
    );
33
  }
34

35
  if (!sleepRecord) {
36
    return null;
37
  }
38

39
  return <EditSleepForm id={id} sleepRecord={sleepRecord} />;
40
}
41

42
function EditSleepForm({ id, sleepRecord }: { id: string; sleepRecord: SleepRecord }) {
43
  const updateSleepRecord = useUpdateSleepRecord();
44

45
  const [date, setDate] = useState(parseDateOnly(sleepRecord.date));
46
  const [annotations, setAnnotations] = useState(sleepRecord.annotations || "");
47
  const [average, setAverage] = useState(sleepRecord.average);
48

49
  const formatValue = (value: number): string => {
50
    return String(value).replaceAll(".", ",");
51
  };
52

53
  const save = async () => {
54
    const data = {
55
      date,
56
      annotations,
57
      average,
58
    };
59

60
    await updateSleepRecord.mutateAsync({ id: String(id), payload: data });
61
    router.back();
62
  };
63

64
  return (
65
    <KeyboardAvoidingView behavior="height" style={styles.keyboardView}>
66
      <Stack.Screen options={{ title: "Editar Registro" }} />
67
      <ScrollView scrollEventThrottle={16}>
68
        <View style={styles.container}>
69
          <View style={styles.header}>
70
            <View style={styles.innerHeaderWrapper}>
71
              <View style={[styles.headerIcon, { backgroundColor: "#EFF6FF" }]}>
72
                <Ionicons name="moon-outline" size={20} color="#2563EB" />
73
              </View>
74

75
              <View style={styles.headerTitleSubtitle}>
76
                <Text style={styles.headerTitle}>Editar Sono</Text>
77
                <Text style={styles.headerSubtitle}>
78
                  Atualize os dados do sono
79
                </Text>
80
              </View>
81
            </View>
82

83
            <Text style={styles.description}>
84
              Você pode editar este registro nos primeiros 5 minutos após a
85
              criação.
86
            </Text>
87
          </View>
88

89
          <Card style={styles.mainCard}>
90
            <DatePickerField
91
              label="Data do Registro"
92
              initialDate={date}
93
              maximumDate={new Date()}
94
              onChange={setDate}
95
            />
96

97
            <View style={{ marginVertical: 15 }}>
98
              <ScaleSlider
99
                label="Duração"
100
                value={average}
101
                onValueChange={setAverage}
102
                onValueFormat={formatValue}
103
                step={0.5}
104
                min={0.0}
105
                max={15.0}
106
                minLabel="0h"
107
                maxLabel="15h"
108
              />
109
            </View>
110

111
            <TextArea
112
              label="Notas sobre a qualidade"
113
              variant="darkGhost"
114
              onChangeText={(val) => setAnnotations(val)}
115
              value={annotations}
116
              minRows={5}
117
              maxRows={10}
118
              placeholder="Como você se sentiu ao acordar? Teve sonhos marcantes?"
119
            />
120
          </Card>
121

122
          <Button
123
            title="Salvar Alterações"
124
            onPress={save}
125
            loading={updateSleepRecord.isPending}
126
            disabled={updateSleepRecord.isPending}
127
          />
128
        </View>
129
      </ScrollView>
130
    </KeyboardAvoidingView>
131
  );
132
}
133

134
const styles = StyleSheet.create({
135
  container: {
136
    gap: 24,
137
    paddingHorizontal: Spacing.containerPadding,
138
    paddingVertical: Spacing.sectionGap,
139
  },
140
  mainCard: {
141
    padding: Spacing.cardGap,
142
  },
143
  header: {},
144
  headerIcon: {
145
    paddingVertical: 15,
146
    paddingHorizontal: 14,
147
    width: 48,
148
    borderRadius: BorderRadius.md,
149
  },
150
  innerHeaderWrapper: {
151
    flex: 1,
152
    flexDirection: "row",
153
    alignItems: "center",
154
  },
155
  headerTitleSubtitle: {
156
    marginLeft: 10,
157
  },
158
  headerTitle: {
159
    ...Typography.headlineMd,
160
  },
161
  headerSubtitle: {
162
    ...Typography.bodyMd,
163
    color: Colors.light.textSecondary,
164
  },
165
  description: {
166
    ...Typography.bodyMd,
167
    color: Colors.light.textSecondary,
168
    marginTop: 20,
169
  },
170
  keyboardView: {
171
    flex: 1,
172
  },
173
  centered: {
174
    flex: 1,
175
    justifyContent: "center",
176
    alignItems: "center",
177
  },
178
});